﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESpace;

namespace ESpace_Project
{

    public partial class FormUnionCrossRange : Form
    {
        const int W = 10;
        const int H = 5;
        CheckBox[,] chbxMas = new CheckBox[W, H];

        CheckBox[] chbxMas1 = new CheckBox[W];

        public FormUnionCrossRange()
        {
            InitializeComponent();

            for (int i = 0; i < W; i++)
                for (int j = 0; j < H; j++)
                {
                    CheckBox chbx = new CheckBox();
                    chbx.Location = new Point(i * 20+5, j * 20+5);
                    chbx.Width = 18;
                    chbx.Name = "chbx_" + i.ToString() + "_" + j.ToString();
                    chbx.CheckedChanged += new EventHandler(chbx_CheckedChanged);
                    panel1.Controls.Add(chbx);
                    chbxMas[i, j] = chbx;
                }

            for (int i = 0; i < W; i++)
                {
                    CheckBox chbx = new CheckBox();
                    chbx.Location = new Point(i * 20 + 5, 5);
                    chbx.Width = 18;
                    chbx.Name = "chbx1_" + i.ToString();
                    chbx.Enabled = false;
                    panel2.Controls.Add(chbx);
                    chbxMas1[i] = chbx;
                }
        }

        DiapCollection<int> srsDL = new DiapCollection<int>();
        private void chbx_CheckedChanged(object sender, EventArgs e)
        {

            // создаем список диапазонов
            srsDL.Clear();
            for (int j = 0; j < H; j++)
            {
                int startI = -1;
                int endI = -1;
                for (int i = 0; i < W; i++)
                {
                    if (chbxMas[i, j].Checked)
                    {
                        if (startI == -1) startI = i;
                        else endI = i;
                    }
                    else
                    {
                        if (startI != -1)
                        {
                            srsDL.Add(startI, endI == -1 ? startI : endI);
                            startI = -1;
                            endI = -1;
                        }
                    }
                }

                if (startI != -1) srsDL.Add(startI, endI == -1 ? startI : endI);
            }

            listBox1.Items.Clear();
            for (int i = 0; i < srsDL.Count; i++)
            {
                listBox1.Items.Add(srsDL[i].st.ToString() + " - " + srsDL[i].en.ToString());
            }

            DiapCollection<int> destDL = srsDL.UnionListDiap();
            //destDL = UnionListDiap(srsDL);

            
            for (int i = 0; i < W; i++) 
                chbxMas1[i].Checked = false;
            
            listBox2.Items.Clear();
            for (int i = 0; i < destDL.Count; i++)
            {
                listBox2.Items.Add(destDL[i].st.ToString() + " - " + destDL[i].en.ToString());
                for (int j = destDL[i].st; j <= destDL[i].en; j++)
                    chbxMas1[j].Checked = true;
            }

        }

        List<DiapItem<int>> UnionListDiap(List<DiapItem<int>> srsDiap)
        {
            if (srsDiap == null) throw new Exception("Принимаемый список не может быть NULL");
            if (srsDiap.Count == 0) return new List<DiapItem<int>>();

            List<DiapItem<int>> ret = new List<DiapItem<int>>();

            // клонируем в промежуточный список
            List<DiapItem<int>> dpL = new List<DiapItem<int>>();
            for (int i = 0; i < srsDiap.Count; i++)
                dpL.Add(new DiapItem<int>(srsDiap[i].st, srsDiap[i].en));

            ret.Add(new DiapItem<int>(dpL[0].st, dpL[0].en)); // новый диапазон
            dpL.RemoveAt(0);
            while (dpL.Count > 0)
            {
                for (int n = 0; n < ret.Count; n++)
                {
                    if (dpL.Count == 0) break;

                    DiapItem<int> diap = ret[n];
                    bool bUnion = false;
                    for (int i = 0; i < dpL.Count; i++)
                    {

                        // если есть перекрещивание: объединяем, и удаляем не нужный более для проверки элемент   
                        if (diap.st <= dpL[i].st && diap.en >= dpL[i].st)
                        {
                            if (diap.en < dpL[i].en) diap.en = dpL[i].en;
                            dpL.RemoveAt(i); i--;
                            bUnion = true;
                        }
                        else if (diap.en >= dpL[i].en && diap.st <= dpL[i].en)
                        {
                            if (diap.st > dpL[i].st) diap.st = dpL[i].st;
                            dpL.RemoveAt(i); i--;
                            bUnion = true;
                        }
                        else if (diap.st > dpL[i].st && diap.en < dpL[i].en)
                        {
                            diap.st = dpL[i].st;
                            diap.en = dpL[i].en;
                            dpL.RemoveAt(i); i--;
                            bUnion = true;
                        }
                    }

                    if (!bUnion)
                    {
                        ret.Add(dpL[0]);
                        dpL.RemoveAt(0);
                    }
                }
            }


            return ret;
        }

    }

}
